package org.imagiccode.core.util;

import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.context.ContextLoader;
import org.springframework.web.context.WebApplicationContext;

import java.io.Serializable;
import java.util.Date;
import java.util.concurrent.TimeUnit;

/**
 * Redis的工具类
 *
 * @author 1340760685@qq.com
 * @create 2016-12-05 21:12
 **/
public final class RedisUtil {
    private RedisUtil(){
    }
    private static RedisTemplate<Serializable,Serializable> redisTemplate=null;
    private static Integer EXPIRE=PropertiesUtil.getInt("redis.expiration");
    /**
     * 获取连接
     */
    private static RedisTemplate<Serializable,Serializable> getRedis(){
      if(redisTemplate==null){
          synchronized (RedisUtil.class){
              if(redisTemplate==null){
                  WebApplicationContext wac= ContextLoader.getCurrentWebApplicationContext();
                  redisTemplate= (RedisTemplate<Serializable, Serializable>) wac.getBean("redisTemplate");
              }
          }
      }
      return redisTemplate;
    }
    public static final Serializable get(final String key){
       expire(key,EXPIRE);
        return getRedis().opsForValue().get(key);
    }

    public static final void set(final String key,final Serializable value){
        getRedis().boundValueOps(key).set(value);
        expire(key,EXPIRE);
    }
    public static final Boolean exists(final String key){
        expire(key,EXPIRE);
        return getRedis().hasKey(key);
    }
    public static final void del(final String key){
        getRedis().delete(key);
    }

    public static final void deleteAll(final String pattern){
       getRedis().delete(getRedis().keys(pattern));
    }

    public static final String type(final String key){
        expire(key,EXPIRE);
        return getRedis().type(key).getClass().getName();
    }

    /**
     * 在某个时间点失效
     */
    public static final Boolean expireAt(final String key,final long unixTime){
        return getRedis().expireAt(key,new Date(unixTime));
    }
    /**
     * 在某段时间内失效
     */
    public static final Boolean expire(final String key,final int seconds){
        return getRedis().expire(key,seconds, TimeUnit.SECONDS);
    }

    public static final Long ttl(final String key){
        return getRedis().getExpire(key, TimeUnit.SECONDS);
    }

    public static final void setrange(final String key,final long offset,final String value){
        expire(key, EXPIRE);
        getRedis().boundValueOps(key).set(value, offset);
    }
    public static final String getrange(final String key, final long startOffset, final long endOffset) {
        expire(key, EXPIRE);
        return getRedis().boundValueOps(key).get(startOffset, endOffset);
    }

    public static final Serializable getSet(final String key, final String value) {
        expire(key, EXPIRE);
        return getRedis().boundValueOps(key).getAndSet(value);
    }

    /** 递增 */
    public static Long incr(final String redisKey) {
        return getRedis().execute(new RedisCallback<Long>() {
            public Long doInRedis(RedisConnection connection) throws DataAccessException {
                return connection.incr(redisKey.getBytes());
            }
        });
    }
    // 未完，待续...
}
